package pl.put.dcs.workManagerServer.projectManager.computingObjectManger.packetManager;

import org.apache.log4j.Logger;
import pl.put.dcs.workManagerServer.classLoaders.LibraryClassLoader;
import pl.put.dcs.workManagerServer.classLoaders.exceptions.LibraryClassLoaderException;
import pl.put.dcs.workManagerServer.serviceConnectors.ControlModuleServerConnector;
import pl.put.dcs.workManagerServer.serviceConnectors.ControlModuleServerConnectorInterface;
import pl.put.model.computingObject.ComputingObjectDefinition;
import pl.put.model.flowModel.flowComputingObjectElement.FlowComputingObjectElement;
import pl.put.model.packet.DataPacket;
import pl.put.model.packet.Packet;
import pl.put.model.decompositors.dataDecompositor.DataDecompositor;
import pl.put.model.decompositors.tastDecompositor.TaskDecompositor;

// <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
// #[regen=yes,id=DCE.79785E4B-F597-9509-C7D8-9D6ABE54849C]
// </editor-fold> 
public class PacketManager
{

    public static Logger log = Logger.getLogger( PacketManager.class.getName() );
    
    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.69662A21-8918-CADA-4A33-011DA67B6939]
    // </editor-fold> 
    private DataDecompositor dataDecompositor;

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.949350F6-D176-474B-752F-A2900176EA03]
    // </editor-fold> 
    private TaskDecompositor taskDecompositor;
    
    private FlowComputingObjectElement flowComputingObjectElement;

    private ControlModuleServerConnectorInterface ctrlModule;

    public PacketManager( FlowComputingObjectElement flowComputingObjectElement )
    {
        ctrlModule = ControlModuleServerConnector.getInstance();
        try
        {
            this.flowComputingObjectElement = flowComputingObjectElement;
            LibraryClassLoader libClassLoader = LibraryClassLoader.getInstance();
            // data decompositor
            String dataDecomp = flowComputingObjectElement.getDataDecompositorClassPath();
            log.debug( "Load data decompositor. Path to class: " + dataDecomp );
            dataDecompositor = ( DataDecompositor )libClassLoader.create( dataDecomp );
            dataDecompositor.createNextDataPacket();
            // task decompositor
            String taskDecomp = flowComputingObjectElement.getTaskDecompositorClassPath();
            //taskDecompositor = ( TaskDecompositor )libClassLoader.create( taskDecomp );
        }
        catch ( LibraryClassLoaderException ex )
        {
            log.error( "Error in CO configuration. Can't load data or task decompositor" );
            ex.printStackTrace();
            log.error( ex );
        }
    }


    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.9D703C0F-3499-D2F3-E468-6E03B73147DF]
    // </editor-fold> 
    public Packet createPacket()
    {
        DataPacket dataPacket = dataDecompositor.createNextDataPacket();
        ComputingObjectDefinition coDefinition = taskDecompositor.createTask( dataPacket );
        Packet packet = new Packet( dataPacket, coDefinition );
        // powiadomienia modulu informacyjnego, ze zostal wygenerowany pakiet. Podawana jest, takze informcja do, jakiego projektu nalezy.
        // zwrocony jest obiekt, ktory zawiera uzupelniona inforamcje o id packeta. CZY LEPIEJ WYKORZYSTAC REFERENCJE?
        packet.setFlowComputingObjectElement( flowComputingObjectElement );
        packet = ctrlModule.addPacket( packet );
        return packet;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.33DA55E6-7571-DFE6-31D9-677B56433BCA]
    // </editor-fold> 
    public DataDecompositor getDataDecompositor()
    {
        return dataDecompositor;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.7557E64F-CEE7-1D40-2FFE-9745B10941BB]
    // </editor-fold> 
    public void setDataDecompositor( DataDecompositor val )
    {
        dataDecompositor = val;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.AEE26A6B-FD83-D6B6-EC74-6ACD22CB4EF7]
    // </editor-fold> 
    public boolean hasMorePackets()
    {
        return true;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.866F555E-4752-4C78-7113-DC83AC2FF53B]
    // </editor-fold> 
    public TaskDecompositor getTaskDecompositor()
    {
        return taskDecompositor;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.04B3E82E-40D9-9E19-E796-10F2FB748353]
    // </editor-fold> 
    public void setTaskDecompositor( TaskDecompositor val )
    {
        taskDecompositor = val;
    }

}

